#include "stdafx.h"

#include "../comi/xot.h"
#include "../arch/fmtrec.h"
#include "../file/natvfile.h"
#include "../file/logicfile.h"
#include "../arch/pe/petools.h"
#include "../arch/pe/arhcpe.h"
#include "../arch/pe/trunkfetch.h"
#include "../coder/zlib.coder.h"
//#include "../coder/lzma.coder.h"
#include "../engine/session.h"
#include "../engine/exu.h"
#include "../mp/mp.h"
#include "../mdf/libmgr.h"
//////////////////////////////////////////////////////////////////////////
#include "../xdo/xdo.swf.h"
#include "../xdo/xdo.xpack.a.h"
#include "../xdo/xdo.xpack.b.h"
#include "../xdo/xdo.maldoc.h"
#include "../xdo/xdo.crypto.a.h"
#include "../xdo/xdo.virut.ce.h"
//////////////////////////////////////////////////////////////////////////

#include "../formal/wrapper.h"

namespace xm
{
	typedef HRESULT (*TGetClassObject)(const IID&, void**);

	struct CLASS_REGISTER_ITEM
	{
		PROGID			ProgId;
		TGetClassObject	pfnGetClassObject;
	};

	CLASS_REGISTER_ITEM ClassRegistryTable [] = 
	{
		{ PROGIDOF(KFormats),			TStdClsFactory<KFormats>::GetClassObject }, 
		{ PROGIDOF(WinPeParser),		TStdClsFactory<WinPeParser>::GetClassObject }, 
		{ PROGIDOF(WinNativeFile),		TStdClsFactory<WinNativeFile>::GetClassObject }, 
		{ PROGIDOF(XdoXPackA),			TStdClsFactory<XdoXPackA>::GetClassObject }, 
		{ PROGIDOF(XdoXPackB),			TStdClsFactory<XdoXPackB>::GetClassObject }, 
		{ PROGIDOF(InflateCoderLL),		TStdClsFactory<coder::InflateCoderLL>::GetClassObject }, 
		{ PROGIDOF(DeflateCoderLL),		TStdClsFactory<coder::DeflateCoderLL>::GetClassObject }, 
		{ PROGIDOF(XdoSwfExploit),		TStdClsFactory<XdoSwfExploit>::GetClassObject }, 
		{ PROGIDOF(VirtualFile),		TStdClsFactory<KVirtualFile>::GetClassObject }, 
		{ PROGIDOF(MemoryFile),			TStdClsFactory<MemoryFile>::GetClassObject }, 
		{ PROGIDOF(XoTable),			TStdClsFactory<XoTable>::GetClassObject }, 
		{ PROGIDOF(DetectSession),		TStdClsFactory<DetectSession>::GetClassObject }, 
		{ PROGIDOF(XdoChain),			TStdClsFactory<XdoChain>::GetClassObject }, 
		{ PROGIDOF(XdoBinExploit1),		TStdClsFactory<XdoBinExploit1>::GetClassObject }, 
		{ PROGIDOF(MDTManager),			TStdClsFactory<MDTManager>::GetClassObject }, 
		{ PROGIDOF(XManEngine),			TStdClsFactory<XManEngine>::GetClassObject }, 
		{ PROGIDOF(WinPETools),			TStdClsFactory<WinPETools>::GetClassObject }, 
		{ PROGIDOF(WinPEThunkFetcher),	TStdClsFactory<WinPEThunkFetcher>::GetClassObject }, 
		{ PROGIDOF(Arguments),			TStdClsFactory<Arguments>::GetClassObject },
		{ PROGIDOF(XdoXPackC),			TStdClsFactory<XdoXPackC>::GetClassObject }, 
		{ PROGIDOF(XdoCryptoA),			TStdClsFactory<XdoCryptoA>::GetClassObject }, 
		{ PROGIDOF(XdoAntiEmuA),		TStdClsFactory<XdoAntiEmuA>::GetClassObject }, 
		{ PROGIDOF(XdoObfusA),			TStdClsFactory<XdoObfusA>::GetClassObject }, 
		{ PROGIDOF(XdoCryptoB),			TStdClsFactory<XdoCryptoB>::GetClassObject }, 
		{ PROGIDOF(XdoVirutCe),			TStdClsFactory<XdoVirutCe>::GetClassObject }, 
	};
};

using namespace xm;

EXTERN_C HRESULT WINAPI GetClassObject( TCLSIDREF rclsid, const IID& riid, void **ppv)
{
	for(size_t i = 0; i < sizeof(ClassRegistryTable)/sizeof(ClassRegistryTable[0]); ++i)
	{
		if( rclsid == ClassRegistryTable[i].ProgId )
		{
			return ClassRegistryTable[i].pfnGetClassObject(riid, ppv);
		}
	}
	return E_INVALIDARG;
}

EXTERN_C HRESULT WINAPI XmCreateInstance( TCLSIDREF rclsid, IUnknown* outer, REFIID riid, void** ppv, IUnknown* xt )
{
	optr<IKClassFactory> pfac;
	RFAILED(GetClassObject( rclsid, face_id(IKClassFactory), (void**)&pfac));
	return pfac->CreateInstance( xt, outer, riid, ppv );
}
